package SampleScripts;

//  <GranitePro>
//  by Decurse 
//  PURCHASE THE EXCLUSIVE VERSION HERE: http://e-junkie.com/decurse/
/*
^^ FEATURES ^^
->  Runs from combat!
->  Logs out when your last full waterskin has been sipped from.
->  Features all anti-ban (that are currently working).
->  Will turn screen to avoid bot-like features.
->  Checks Mining stats to avoid bot-like features.
->  Includes a progress report on the left hand side!
 */
import java.awt.Color;
import java.awt.Graphics;
import java.util.Map;

import org.rsbot.event.events.ServerMessageEvent;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.event.listeners.ServerMessageListener;
import org.rsbot.script.Constants;
import org.rsbot.script.Script;
import org.rsbot.script.ScriptManifest;
import org.rsbot.script.wrappers.RSObject;
import org.rsbot.script.wrappers.RSTile;

@ScriptManifest(authors = {"Decurse"}, category = "Mining", name = "GranitePro", version = 1.5, description = "<html>\n<head>\n</head>\n<body bgcolor='#eeeeee'>\n<center><font size='6' family='serif'><b>GranitePro</b></font><br><font size='3' family='sans-serif'>by Decurse</font> <b><font color=red> Buy the exclusive:  <a href='http://e-junkie.com/decurse/'>http://e-junkie.com/decurse/</a> </b></font></center>\n<br><center><form><font size='3'>Sandstone:</font> <input type='radio' name='mode' value='1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size='3'>Granite:</font><input type='radio' name='mode' value='0'></form><br></center><center>Using Enchanted tiara? <input type='checkbox' name='tiara' value='0'></center><b><font size='5'><center>Terms of Use</center></font></b><center>I agree to the Terms of Use: <input type='checkbox' name='agreement' value='true' align='center'> <br><br> <small>The user Decurse and/or Decurse Networking are not held responsible for damages caused to your computer, network, or account in usage.</small><b><font size='5'><center>Features</center></font></b><div align='left'><ul><li>Runs from combat!<li>Logs out when your last full waterskin has been sipped from.<li>Features all anti-ban (that are currently working).<li>Will turn screen to avoid bot-like features.<li>Checks Mining stats to avoid bot-like features.<li>Includes a progress report on the left hand side!</ul></div>\n\n</body>\n</html>\n")
public class GranitePro extends Script implements PaintListener,
        ServerMessageListener {

    public boolean agreement;
    int avgPerHour;
    long avoidedCombat;
    long avoidedSmokingRocks;
    int checkTime;
    int countToNext;
    int fails;
    int[] gear = new int[]{1265, // Bronze Pickaxe
        1267, // Iron pickaxe.
        1269, // Steel Pickaxe
        1273, // Mithril Pickaxe
        1271, // Adamanite Pickaxe.
        1275, // Rune pickaxe
        13661, // Inferno Adze pickaxe.
        14107, // SC pickaxe
        1823, 1825, 1827, 1829, 1831, // Waterskins
        995, // GP (money)
        14664, // Reward box from randoms
        2528 // Genie Lamp
    };
    long lastAvgCheck;
    long lastCheck;
    final int MAX_FAILS = 10;
    int mode;
    int oldExp;
    int oldLevels;
    int oldRockCount;
    boolean powerMode = false;
    int randomRun = random(40, 75);
    int rockCount;
    int[][] rocks = new int[][]{
        // Granite
        new int[]{10947},
        // Sandstone
        new int[]{10946}};
    final int S_DROP = 3000;
    final int S_MINE = 2000;
    final int S_WALKTO_MINE = 1000;
    final int[] smokingRocks = {11433, 11434, 11435, 11436, 11193};
    int startExp;
    int startLevel;
    long startTime;
    int state = S_MINE;
    int tiara;
    RSTile[] toMine;
    boolean useTiara = false;
    public final int WATERSKIN = 1823;
    int xpPerRock;

    private int antiBan() {
        final int gamble = random(1, 12);

        switch (gamble) {
            case 1:
                return random(500, 750);

            case 2:
                final int x = random(0, 750);
                final int y = random(0, 500);
                moveMouse(0, 0, x, y);
                return random(500, 750);

            case 3:
                openTab(Constants.TAB_INVENTORY);
                return random(500, 750);

            case 4:
                if (getMyPlayer().isMoving()) {
                    return random(750, 1000);
                }

                if (System.currentTimeMillis() - lastCheck >= checkTime) {
                    lastCheck = System.currentTimeMillis();
                    checkTime = random(60000, 180000);

                    if (getCurrentTab() != Constants.TAB_STATS) {
                        openTab(Constants.TAB_STATS);
                    }
                    moveMouse(660, 227, 50, 28);
                    return random(2000, 2800);
                }

            case 5:
                if (random(1, 8) == 2) {
                    int angle = getCameraAngle() + random(-90, 90);
                    if (angle < 0) {
                        angle = 0;
                    }
                    if (angle > 359) {
                        angle = 0;
                    }

                    setCameraRotation(angle);
                }

                return random(500, 750);
        }

        return random(500, 750);
    }

    public String getTermsAndConditions() {
        return "By using this script you agree the the user Decurse nor Decurse Networking be held liable for any damages caused to your computer, network, or account used.";
    }

    @Override
    public int loop() {
        if (!useTiara) {
            if (!inventoryContains(WATERSKIN)) {
                // Do we have any full Waterskins? If not, log out.
                log("Out of any full waterskins - Logging out to keep you alive.");
                logout();
                stopScript();
                return -1;
            }
        }

        // Do we have energy to run? If so, let's run.
        if (getEnergy() >= randomRun && !isRunning()) {
            // All conditions met, set run mode.
            log("Now running..");
            setRun(true);

            randomRun = random(40, 75);
            log("Running again at " + randomRun + " energy.");
            return random(500, 750);
        }

        // Perform script actions based on state.
        switch (state) {
            case S_WALKTO_MINE:
                if (walkPath(toMine)) {
                    log("Now mining..");
                    state = S_MINE;
                    return random(200, 400);
                } else {
                    antiBan();
                    return random(250, 500);
                }

            case S_MINE:
                final RSObject rock = getNearestObjectByID(rocks[mode]);
                final RSObject sr = getNearestObjectByID(smokingRocks);

                // Is the inventory full? Switch to drop mode and get rid of some
                // things.
                if (isInventoryFull()) {
                    if (powerMode) {
                        log("Inventory is full.  Now dropping..");
                        state = S_DROP;
                        return random(1, 100);
                    }
                }

                // Are we in combat? Let's run.
                if (getMyPlayer().isInCombat() && !getMyPlayer().isMoving()) // If
                {
                    log("In combat, attempting to run..");
                    runAway();
                    avoidedCombat++;
                    return random(400, 700);

                }

                if (getMyPlayer().isMoving() || getMyPlayer().getAnimation() != -1) {
                    if (sr != null && distanceTo(sr.getLocation()) <= 1) {
                        log("Rocks are smoking, trying to avoid..");
                        avoidedSmokingRocks++;
                    } else {
                        return antiBan();
                    }
                }
                // Can we find any rocks? If not, try again.
                if (rock != null) {
                    if (tileOnScreen(rock.getLocation())) {
                        fails = 0;
                        atObject(rock, "Mine");
                        return random(250, 320);
                    } else {
                        walkTileRand(rock.getLocation());
                        return random(500, 750);
                    }
                } else {
                    fails++;
                    log("Failed to find a rock, trying " + (MAX_FAILS - fails)
                            + " times.");
                    return random(750, 1500);
                }
            // Drop mode.
            case S_DROP:
                log("Dropping all items except gear.");
                dropAllExcept(gear);
                state = S_MINE;
                return random(1, 100);

        }

        return random(500, 750);
    }

    public void onRepaint(final Graphics g) {
        // local objects:
        final Color WHITE = new Color(255, 255, 255, 255);
        final int index = Constants.STAT_MINING;
        int exp;
        int levels;
        long hours = 0, minutes = 0, seconds;
        long time;

        // Has start time been previously set?
        if (startTime == 0) {
            startTime = System.currentTimeMillis();
        }

        // Calculate hours, minutes and seconds.
        time = System.currentTimeMillis() - startTime;
        seconds = time / 1000;
        if (seconds >= 60) {
            minutes = seconds / 60;
            seconds -= minutes * 60;
        }
        if (minutes >= 60) {
            hours = minutes / 60;
            minutes -= hours * 60;
        }

        // Has variables been previously defined?
        if (startLevel == 0 || startExp == 0) {
            // No, so define them now.
            startLevel = skills.getCurrentSkillLevel(index);
            startExp = skills.getCurrentSkillExp(index);
            oldExp = 0;
        }

        // Calculate catches based on experience changes.
        exp = skills.getCurrentSkillExp(index) - startExp;
        if (exp > oldExp) {
            xpPerRock = exp - oldExp;
            oldExp = exp;
            rockCount++;
            countToNext = skills.getXPToNextLevel(Constants.STAT_MINING)
                    / xpPerRock + 1;

        }

        // Calculate levels gained.
        levels = skills.getCurrentSkillLevel(index) - startLevel;
        if (levels > oldLevels) {
            oldLevels = levels;
        }

        // trytohide: copyright decurse.net

        // Draw information.
        g.setColor(new Color(64, 64, 64, 170));
        g.fillRoundRect(3, 180, 160, 160, 9, 5);
        g.setColor(WHITE);
        g.drawString(getClass().getAnnotation(ScriptManifest.class).name()
                + " v"
                + getClass().getAnnotation(ScriptManifest.class).version(), 9,
                203);
        g.drawString("             by Decurse ", 9, 219);
        g.drawString("XP Gained: " + exp, 9, 235);
        g.drawString("Levels Gained: " + levels, 9, 251);
        g.drawString("Percent to next level: "
                + skills.getPercentToNextLevel(index), 9, 267);
        g.drawString("Times avoided combat: " + avoidedCombat, 9, 283);
        g.drawString("Smoking Rocks Avoided: " + avoidedSmokingRocks, 9, 299);
        g.drawString("Time running: " + hours + ":" + minutes + ":" + seconds,
                9, 315);
        g.drawString("  >>  http://decurse.net  <<", 9, 331);
    }

    @Override
    public boolean onStart(final Map<String, String> args) {
        try {
            mode = Integer.parseInt(args.get("mode"));
            powerMode = true;

            tiara = Integer.parseInt(args.get("tiara"));
            useTiara = true;

            // tos
            agreement = args.get("agreement") != null;
            if (!agreement) {
                log("The agreement to use GranitePro was not accepted. \n By not accepting the Terms of Use, you are not allowed to run the script.");
                return false;
            }
            log("  -  Agreement accepted.");
            log("  -  Powermining activated.");
            log("  -  Thank you for using GranitePro v"
                    + getClass().getAnnotation(ScriptManifest.class).version());

            return true;
            // end
        } catch (final Exception ignored) {
        }
        return true;
    }

    public void runAway() { // running away and running back after a while
        RSTile foo, bar;
        foo = getMyPlayer().getLocation();
        setRun(true);

        bar = new RSTile(foo.getX() + random(10, 12), foo.getY()
                + random(10, 12));

        walkTo(bar);
        while (getMyPlayer().isMoving()) {
            wait(random(2000, 4000));
        }
        wait(random(3000, 5000));
        walkTo(foo);
    }

    public void serverMessageRecieved(final ServerMessageEvent e) {
        final String word = e.getMessage().toLowerCase();
        if (word.contains("died")) {
            log("You have died!  Logging you out to prevent you from being banned.");
            logout();
            stopScript();
        }
    }

    private boolean walkPath(final RSTile[] path) {
        if (distanceTo(path[path.length - 1]) <= 2) {
            return true;
        } else {
            if (!getMyPlayer().isMoving()) {
                walkPathMM(randomizePath(path, 2, 2), 20);
            }
        }

        return false;
    }

    private void walkTileRand(final RSTile tile) {
        // Local objects:
        final RSTile temp = new RSTile(tile.getX() + random(-2, 2), tile.getY()
                + random(-2, 2));

        walkTo(temp);
    }
}
